/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import ts from '../../vendor/ohos-typescript';

export type Method = {
  name: string;
  static: boolean;
  line: number;
  character: number;
  endCol: number;
};


export function getMemberMethod(member: ts.Node, sourceFile: ts.SourceFile): Method | null {
  const position = member.getStart();
  const endPosition = member.getEnd();
  const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, position);
  const { character: endChar } = ts.getLineAndCharacterOfPosition(sourceFile, endPosition);

  if (ts.isCallSignatureDeclaration(member)) {
    return { name: ' call ', static: false, line: line + 1, character: character + 1, endCol: endChar + 1 };
  }
  if (ts.isConstructorDeclaration(member)) {
    return { name: ' construct ', static: false, line: line + 1, character: character + 1, endCol: endChar + 1 };
  }

  let name: string | null = null;
  let isStatic = false;

  if (ts.isMethodSignature(member) || ts.isMethodDeclaration(member)) {
    if (member.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword)) {
      return null;
    }
    if (member.name && ts.isComputedPropertyName(member.name)) {
      const expr = member.name.expression;
      name = ts.isStringLiteral(expr) ? expr.text :
        ts.isIdentifier(expr) ? expr.text : null;
    } else if (ts.isIdentifier(member.name)) {
      name = member.name.text;
    } else if (ts.isPrivateIdentifier(member.name)) {
      name = `#${member.name.text}`;
    }
    isStatic = member.modifiers?.some(mod => mod.kind === ts.SyntaxKind.StaticKeyword) ?? false;
  } else if (ts.isFunctionDeclaration(member)) {
    name = member.name?.text ?? null;
  }

  return name ? { name, static: isStatic, line: line + 1, character: character + 1, endCol: endChar + 1 } : null;
}

export function isSameMethod(method1: Method, method2: Method): boolean {
  if (method1 === null || method2 === null) { return false };
  if (method1.name === ' call ' && method2.name === ' call ') { return true };
  if (method1.name === ' construct ' && method2.name === ' construct ') { return true };
  return method1.name === method2.name && method1.static === method2.static;
}

export function hasMatchingSetMethod(method: ts.GetAccessorDeclaration): boolean {
  const parent = method.parent as ts.ClassDeclaration;
  return parent.members.some(
    member => ts.isSetAccessorDeclaration(member) && 
    member.name.getText().replace(/\/\*.*?\*\//g, '').replace(/^\[['"`]|['"`]\]$/g, '').trim() === 
    method.name.getText().replace(/\/\*.*?\*\//g, '').replace(/^\[['"`]|['"`]\]$/g, '').trim()
  );
}

export function isNumberArgument(node: ts.Expression): boolean {
  return ts.isNumericLiteral(node) ||
    (ts.isIdentifier(node) && /^\d+$/.test(node.text));
}
